#include "Protocols/SMTP.h"
#include "utilities/ReadablePacket.h"
#include "protocols/ProtocalCode.h"
#include "protocols/ProtocalPool.h"
#include "protocols/ShowableItem.h"
#include "utilities/utilities.h"

REGISTER_PROTOCOL(SmtpProtocal)

int SmtpHeader::spaceIndex() const{
	QByteArray data = QByteArray::fromRawData((const char *)mData, getHeaderLength() - 2);
	return data.indexOf(" ");
}

SmtpHeader::_mType SmtpHeader::typeFlag() const
{
	if (spaceIndex() > 0){
		QString& data = byteToString((const char *)mData, " ");
		if ("HELLO" == data || "MAIL" == data || "RCPT" == data || "DATA" == data || "VRFY" == data || "EXPN" == data || "HELP" == data ||
			"NOOP" == data || "QUIT" == data || "RESET" == data){
			return REQUEST;
		}else{
			return RESPONSE;
		}
	} 
	else{
		return MESSAGE;
	}
}

void SmtpHeader::toShowableItems(ShowableItem* root) const
{
	int pos = mPos;
	ShowableItem* tmp,* flags;

	ShowableItem* protocal = createProtocalItem("Simple Mail Transfer Protocol", pos, getHeaderLength());
	root->pushChild(protocal);

	if (MESSAGE != typeFlag())
	{
		tmp = createItemUnchange(qPrintable(byteToString((const char *)mData, "\r\n")), "", "", pos, getHeaderLength());
		protocal->pushChild(tmp);

		if (RESPONSE == typeFlag())
		{
			QString& data =  byteToString((const char *)mData, " ");
			flags = createItem("Response code: ",data, pos, spaceIndex());
			tmp->pushChild(flags);

			QString& ndata = byteToString((const char *)(mData + spaceIndex() + 1), "\r\n");
			flags = createItem("Response arg: ", ndata, ++pos, ndata.size());
			tmp->pushChild(flags);

			if (ndata.size() != (getHeaderLength() - spaceIndex() - 3))
			{
				tmp = createItem(qPrintable(QString("Data ( %1 bytes )").arg(getHeaderLength() - spaceIndex() - 1)), "", pos, getHeaderLength() - spaceIndex() - 1);
				protocal->pushChild(tmp);
			}
		}else{		
			flags = createItem("Request command: ",byteToString((const char *)mData, " "), pos, spaceIndex());
			tmp->pushChild(flags);

			flags = createItem("Request arg: ", byteToString((const char *)(mData + spaceIndex() + 1), "\r\n"), ++pos, getHeaderLength() - spaceIndex() - 3);
			tmp->pushChild(flags);
		}
	}else{
		QStringList strList = getMessageList();
		QStringList::const_iterator iter = strList.begin();
		while(iter < strList.end() )
		{
			if (*iter == "")
			{
				++ iter;
				continue;
			}
			tmp = createItem(qPrintable(QString("Message :")), *iter, pos, (*iter).size());
			protocal->pushChild(tmp);
			++ iter;
		}
	}
}

SmtpProtocal::SmtpProtocal() : Protocol(SMTP,QString("SMTP"))
{
	shared_ptr<AppProtocolProperty> prop = make_shared<AppProtocolProperty>();
	prop->mDefaultPort.push_back(25);
	mInfo = prop;
}

boost::shared_ptr<PacketHeader> 
SmtpProtocal::analyzeProc(boost::shared_ptr<ReadablePacket> packet,int low,int high,boost::shared_ptr<Protocol>& tip)
{
	boost::shared_ptr<SmtpHeader> header(make_shared<SmtpHeader>(SmtpProtocal_register.m_Instance,packet->getData(),low,high - low + 1));

	tip.reset();

	return header;
}

QString SmtpHeader::getSummary() const
{
	if (MESSAGE != typeFlag())
	{
		QByteArray data = QByteArray::fromRawData((const char *)mData, getHeaderLength() - 2);
		return	QString(data);
	}else{
		QString str = "";
		QStringList strList = getMessageList();
		QStringList::const_iterator iter = strList.begin();
		str += *iter + " " + *(++iter);
		return str;
	}
}

QStringList SmtpHeader::getMessageList() const
{
	QByteArray data = QByteArray::fromRawData((const char *)mData,getHeaderLength());
	QString strdata(data);

	return strdata.split("\r\n");
}